package com.lw.demo1;

import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReentrantLock;

/**
 * @author LW
 * @2020/8/19 10:55
 */
public class SaleTicketDemo2 {

    public static void main(String[] args) {
        //并发：多线程操作同一个资源类
        Ticket2 ticket = new Ticket2();
        //@FunctionalInterface  函数式接口    jdk1.8后使用lambda表达式
        new Thread(()->{
            for (int i = 0; i <= 60; i++) ticket.sale();//for循环只有一句的时候括号可以不要
        },"张三").start();
        new Thread(()->{
            for (int i = 0; i <= 60; i++) ticket.sale();
        },"李四").start();
        new Thread(()->{
            for (int i = 0; i <= 60; i++) ticket.sale();
        },"王五").start();

    }
}

//资源类 OOP
class Ticket2{
    //属性、方法（低耦合）
    private int num=50;
    /**公平锁FairSync: 十分公平，先来后到，不可以插队
     * 非公平锁NonfairSync：十分不公平，可以插队（默认）
     * 涉及CPU调度，耗时少优先（高响应比优先算法）
     */

    //ReentrantLock参数为空时，是非公平锁NonfairSync
    //含有一个布尔值的参数时，是公平锁FairSync
    Lock lock = new ReentrantLock();

    /**Lock三步
     * 1.new ReentrantLock();
     * 2.lock.lock();加锁
     * finally-->lock.unlock();解锁
     */

    //卖票的方式
    //synchronized 本质：队列、锁
    public void sale(){
        lock.lock();
        //lock.tryLock();//尝试获取锁

        try {
            //业务代码
            if (num>0){
                System.out.println(Thread.currentThread().getName()+"卖出了"+(num--)+"票，剩余："+(50-(num--)));
            }
        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            lock.unlock();
        }

    }
}
